#pragma once

#include <cassert>
#include <string>

#include <barcodeart/ABarCode.hpp>
#include <barcodeart/qrcode/IQRCode.hpp>
#include <barcodeart/qrcode/EncoderConfig.hpp>

#include "barcodeart/qrcode/qrencode/qrcode_libqrencode_global.hpp"
#include "barcodeart/qrcode/qrencode/import_libqrencode.hpp"

namespace barcodeart
{

namespace qrcode
{

namespace qrencode
{

class QRCODE_LIBQRENCODESHARED_EXPORT QRCode : public IQRCode, public ABarCode
{
public:
    QRCode(clib::QRcode* pQRcode) : m_pQRcode(pQRcode)
    {
        assert(m_pQRcode);
    }

    ~QRCode() { clib::QRcode_free(m_pQRcode); }

    int getVersion() const { return m_pQRcode->version; }
    int getWidth() const { return m_pQRcode->width; }
    int getHeight() const { return getWidth(); }
    unsigned char* getData() const { return m_pQRcode->data; }
    int getDataSize() const { return getWidth() * getWidth(); }
    std::string getDataAsString() { return std::string(reinterpret_cast<const char*>(getData()), getDataSize()); }

    unsigned char& getData(int y, int x) { return getData()[y*getWidth() + x]; }
    const unsigned char& getData(int y, int x) const { return getData()[y*getWidth() + x]; }
    bool isBlack(unsigned char data) const { return data & 1; }
    bool isBlack(int y, int x) const { return isBlack(getData(y, x)); }

    operator clib::QRcode*() const { return m_pQRcode; }
private:
    clib::QRcode* m_pQRcode;
};

}

}

}
